home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / ldexp.c < prev    next >
C/C++ Source or Header  |  1991-12-03  |  2KB  |  57 lines

  1. /*
  2.  * ldexp.c --
  3.  *
  4.  *      Source code for the ldexp library function.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = 
  18.     "$Header: /sprite/src/lib/c/etc/RCS/ldexp.c,v 1.2 91/12/02 21:51:16 kupfer Exp $ SPRITE (Berkeley)";
  19. #endif not lint
  20.      
  21. #include <stdio.h>
  22. #include "errno.h"
  23. /* Largest signed long int power of 2 */
  24. #define MAXSHIFT        (8 * sizeof(long) - 2)   
  25.  
  26. #define    MAXFLOAT    1.7e308
  27.  
  28. double ldexp(value, exp)
  29.      double value;
  30.      int    exp; 
  31. {
  32.  
  33.  
  34.     extern double frexp();
  35.     int    old_exp;
  36.  
  37.         if (exp == 0 || value == 0.0) /* nothing to do for zero */
  38.                 return (value);
  39.         (void) frexp(value, &old_exp);
  40.         if (exp > 0) {
  41.                 if (exp + old_exp > 1023) { /* overflow */
  42.                         errno = ERANGE;
  43.                         return (value < 0 ? -MAXFLOAT : MAXFLOAT);
  44.                 }
  45.                 for ( ; exp > MAXSHIFT; exp -= MAXSHIFT)
  46.                         value *= (1L << MAXSHIFT);
  47.                 return (value * (1L << exp));
  48.         }
  49.         if (exp + old_exp < -1023) { /* underflow */
  50.                 errno = ERANGE;
  51.                 return (0.0);
  52.         }
  53.         for ( ; exp < -MAXSHIFT; exp += MAXSHIFT)
  54.                 value *= 1.0/(1L << MAXSHIFT); /* mult faster than div */
  55.         return (value / (1L << -exp));
  56. }
  57.